<?php

namespace app\common\service\organization;

use app\common\enums\AccountTypeEnum;
use app\common\enums\ClassHourTypeEnum;
use app\common\enums\LevelTypeEnum;
use app\common\enums\organization\OrganizationUpTypeEnum;
use app\common\model\banxi\core\CoreAccountClassHour;
use app\common\model\banxi\organization\Organization as OrganizationModel;
use app\common\model\banxi\organization\OrganizationLevelConfig;
use app\common\model\banxi\organization\OrganizationLevelRw;
use app\common\model\banxi\student\Student;
use app\common\model\banxi\student\Student as StudentModel;
use app\common\service\ApiService;
use app\common\service\core\CoreAccountClassHourService;
use ba\Exception;
use think\db\exception\PDOException;
use think\exception\ValidateException;
use think\facade\Db;

class OrganizationLevelService extends ApiService
{

    // 校区升级
    public function campusUpgrade(string $organizationId)
    {
        $organization = OrganizationModel::where(['id' => $organizationId])->find();
        if (!$organization) {
            //机构不存在
            return false;
        }
        $organizationLevel = $organization['level'];
        $organizationLevelConfigModel = new OrganizationLevelConfig();

        $levelConfig = $organizationLevelConfigModel->where(['id' => $organizationLevel])->find();
        if (empty($levelConfig)) {
            //等级不存在
            return false;
        }
        $levelType = LevelTypeEnum::E1;
        //不是超级校区直接成功
        if ($levelConfig['levelType'] != $levelType) {
            //不是超级校区
            return false;
        }
        $levelConfigList = $organizationLevelConfigModel->where([
            ['levelType', '=', $levelType],
            ['id', '<', $organizationLevel]
        ])->order(['id' => 'desc'])->select()->toArray();
        if (empty($levelConfigList)) {
            //没有可升级的等级
            return false;
        }
        Db::startTrans();
        try {
            $buyClassMinuteTotal = $this->campusUpgradeStatistics($organizationId);
            $upLevelRwDetail = [];
            foreach ($levelConfigList as $item) {
                if ($item['id'] >= $organizationLevel) {
                    continue;
                }
                if ($buyClassMinuteTotal >= $item['upgradeRule']) {
                    $organization->level = $item['id'];
                    $upLevelRwDetail = [
                        'level' => $item['id'],
                        'levelName' => $item['name']
                    ];
                }
            }
            $organization->save();
            if ($upLevelRwDetail) {
                $organizationLevelRwModel = new OrganizationLevelRw();
                $beforeLevel = $levelConfig['id'] ?? 0;
                $beforeLevelName = $levelConfig['name'] ?? '';
                $afterLevel = $upLevelRwDetail['level'];
                $afterLevelName = $upLevelRwDetail['levelName'];
                $organizationLevelRwModel->addUpLevelRw($organizationId, $beforeLevel, $beforeLevelName, $afterLevel, $afterLevelName, OrganizationUpTypeEnum::E1);
            }
            Db::commit();
        } catch (Exception|PDOException|ValidateException $e) {
            Db::rollback();
            $this->setError($e->getMessage());
            return false;
        }
        return true;
    }

    public function campusUpgradeStatistics($organizationId)
    {
        //自营校区+直推校区
        $accountClassHourService = new CoreAccountClassHourService();
        $coreAccountClassHourModel = new CoreAccountClassHour();
        $organizationModel = new OrganizationModel();
        $organizationLevelConfigModel = new organizationLevelConfig();
        //自营校区+直推校区购买总课时
        $buyClassMinuteTotal = 0;
        $organizationSonIds = $organizationModel->getSonOrganization($organizationId);
        foreach ($organizationSonIds as $organId) {
            $organizationLevel = OrganizationModel::where(['id' => $organId])->value('level');
            if (!$organizationLevel) {
                //机构不存在
                continue;
            }
            $isCampus = $organizationLevelConfigModel->judgeLevelIdentity($organizationLevel, LevelTypeEnum::E1);
            if (!$isCampus) {
                //不是校区
                continue;
            }
            $accountClassHour = $accountClassHourService->getByAccountIdAndType($organId, AccountTypeEnum::ORGAN);
            $buyClassMinuteTotal += $coreAccountClassHourModel->buyClassMinuteTotal(ClassHourTypeEnum::C_60, $accountClassHour);
        }
        return $buyClassMinuteTotal;
    }

    //合伙人升级
    public function partnerUpgrade(string $studentId)
    {
        $student = Student::where(['id' => $studentId])->find();
        if (empty($student)) {
            return true;
        }
        $organizationId = $student['organizationId'];
        $organization = OrganizationModel::where(['id' => $organizationId])->find();
        if (!$organization) {
            //机构不存在
            return true;
        }
        $organizationLevel = $organization['level'];
        $organizationLevelConfigModel = new OrganizationLevelConfig();

        $levelConfig = $organizationLevelConfigModel->where(['id' => $organizationLevel])->find();
        if (empty($levelConfig)) {
            //等级不存在
            return true;
        }
        $levelType = LevelTypeEnum::E2;
        //不是超级校区直接成功
        if ($levelConfig['levelType'] != $levelType) {
            //机构不存在
            return true;
        }
        $levelConfigList = $organizationLevelConfigModel->where([
            ['levelType', '=', $levelType],
            ['id', '<', $organizationLevel]
        ])->order(['id' => 'desc'])->select()->toArray();
        if (empty($levelConfigList)) {
            return true;
        }
        Db::startTrans();
        try {
            $studentBuyClassMinute = $this->partnerUpgradeStatistics($organizationId);
            $upLevelRwDetail = [];
            foreach ($levelConfigList as $item) {
                if ($organizationLevel <= $item['id']) {
                    continue;
                }
                $helpNum = 0;
                foreach ($studentBuyClassMinute as $buyClass) {
                    if ($buyClass >= $item['requireClass']) {
                        $helpNum++;
                    }
                }
                if ($helpNum >= $item['upgradeRule']) {
                    $organization->level = $item['id'];
                    $upLevelRwDetail = [
                        'level' => $item['id'],
                        'levelName' => $item['name']
                    ];
                }
            }
            $organization->save();
            if ($upLevelRwDetail) {
                $organizationLevelRwModel = new OrganizationLevelRw();
                $beforeLevel = $levelConfig['id'] ?? 0;
                $beforeLevelName = $levelConfig['name'] ?? '';
                $afterLevel = $upLevelRwDetail['level'];
                $afterLevelName = $upLevelRwDetail['levelName'];
                $organizationLevelRwModel->addUpLevelRw($organizationId, $beforeLevel, $beforeLevelName, $afterLevel, $afterLevelName, OrganizationUpTypeEnum::E1);
            }
            Db::commit();
        } catch (Exception|PDOException|ValidateException $e) {
            Db::rollback();
            $this->setError($e->getMessage());
            return false;
        }
        return true;
    }

    //计算机构下已帮助学生帮助的课时数
    public function partnerUpgradeStatistics($organizationId)
    {
        //当前机构下的学生
        $accountClassHourService = new CoreAccountClassHourService();
        $coreAccountClassHourModel = new CoreAccountClassHour();
        $studentModel = new StudentModel();
        //当前机构下的学生
        $studentIds = $studentModel->getOrganizationStudent($organizationId);
        $studentBuyClassMinute = [];
        foreach ($studentIds as $studentId) {
            $accountClassHour = $accountClassHourService->getByAccountIdAndType($studentId, AccountTypeEnum::STUDENT);
            $studentBuyClassMinute[$studentId] = $coreAccountClassHourModel->buyClassMinuteTotal(ClassHourTypeEnum::C_60, $accountClassHour);
        }
        return $studentBuyClassMinute;
    }
}
